package cn.jinjimi.app.main.dialog;

import android.app.Dialog;
import android.content.Context;
import android.graphics.Color;
import android.graphics.drawable.ColorDrawable;
import android.os.Bundle;
import android.view.Gravity;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.view.Window;
import android.widget.ImageView;
import android.widget.TextView;

import cn.jinjimi.base.util.Lunar;
import cn.jinjimi.app.R;
import cn.jinjimi.app.main.widget.LunarDatePicker;

import java.util.Calendar;
import java.util.Locale;

/**
 * 日期设置dialog
 * 包含公历和农历
 * 可以自由选择
 * Created by Jinsen on 2015/8/4.
 */
public class DatePickerDialog extends Dialog implements View.OnClickListener,
        LunarDatePicker.OnDateChangedListener {

    private static final String YEAR = "year";
    private static final String MONTH = "month";
    private static final String DAY = "day";
    private static final String Hour = "hour";
    private static final String Minute = "minute";
    private static final String DATETYPE = "dateType";

    private LunarDatePicker mDatePicker;
    private OnDateSetListener mCallBack;

    private TextView mHideYearStateTv = null;
    private TextView mTitle = null;

    private boolean mIsHideYear = false;

    private ImageView mGregorianIv = null;
    private ImageView mLunarIv = null;

    Calendar mSetDateCalendar = null;
    String mDateStr = null;

    /**
     * The callback used to indicate the user is done filling in the date.
     */
    public interface OnDateSetListener {
        int TYPE_GREGORIAN_NO_YEAR = 0;
        int TYPE_GREGORIAN_YEAR = 1;
        int TYPE_LUNAR_NO_YEAR = 2;
        int TYPE_LUNAR_YEAR = 3;
        int TYPE_ALL = 4;

        /**
         * @param view
         * @param date    所有的都返回公历的日期
         * @param dateStr 日期字符串 公历的 2015年1月日 农历 二零一五年一月初一
         * @param type    日期类型
         *                TYPE_GREGORIAN_NO_YEAR(0) 无年份公历
         *                TYPE_GREGORIAN_YEAR(1) 有年份公历
         *                TYPE_LUNAR_NO_YEAR(2) 无年份农历
         *                TYPE_LUNAR_YEAR(3)有年份农历
         */
        void onDateSet(LunarDatePicker view, Calendar date, String dateStr, int type);
    }

    public DatePickerDialog(Context context,
                            OnDateSetListener callBack,
                            int type,
                            int year,
                            int monthOfYear,
                            int dayOfMonth) {
        this(context, 0, callBack, type, year, monthOfYear, dayOfMonth, 0, 0);
    }

    public DatePickerDialog(Context context,
                            OnDateSetListener callBack,
                            int type,
                            int year,
                            int monthOfYear,
                            int dayOfMonth,
                            int hour,
                            int minute) {
        this(context, 0, callBack, type, year, monthOfYear, dayOfMonth, hour, minute);
    }

    public DatePickerDialog(Context context,
                            int theme,
                            OnDateSetListener callBack,
                            int type,
                            int year,
                            int monthOfYear,
                            int dayOfMonth,
                            int hour,
                            int minute) {
        super(context, theme);

        mCallBack = callBack;

        requestWindowFeature(Window.FEATURE_NO_TITLE);
        LayoutInflater inflater = LayoutInflater.from(context);
        View contentView = inflater.inflate(R.layout.date_picker_dialog, null);
        setContentView(contentView);

        LunarDatePicker.DATETYPE dateType = LunarDatePicker.DATETYPE.ALL;
        mDatePicker = (LunarDatePicker) contentView.findViewById(R.id.date_picker_datePicker);
        if (type == OnDateSetListener.TYPE_LUNAR_NO_YEAR || type == OnDateSetListener.TYPE_LUNAR_YEAR) {
            dateType = LunarDatePicker.DATETYPE.LUNAR;
            if (type == OnDateSetListener.TYPE_LUNAR_NO_YEAR) {
                mDatePicker.setYearVisible(View.GONE);
            } else {
                mDatePicker.setYearVisible(View.VISIBLE);
            }

            Calendar c = Calendar.getInstance(Locale.CHINA);
            c.set(year, monthOfYear, dayOfMonth, hour, minute);
            Lunar l = new Lunar(c);
            year = l.numeric_year();
            int lm = Lunar.leapMonth(year);
            if ((lm > 0 && l.numbric_month() > lm) || l.isLeapMonth()) {
                monthOfYear = l.numbric_month();
            } else {
                monthOfYear = l.numbric_month() - 1;
            }
            dayOfMonth = l.numbric_day();
        } else if (type == OnDateSetListener.TYPE_GREGORIAN_NO_YEAR || type == OnDateSetListener.TYPE_GREGORIAN_YEAR) {
            dateType = LunarDatePicker.DATETYPE.GREGORIAN;
        } else if (type == OnDateSetListener.TYPE_ALL) {
            dateType = LunarDatePicker.DATETYPE.ALL;
        }

        mDatePicker.init(year, monthOfYear, dayOfMonth, hour, minute, dateType, this);

        contentView.findViewById(R.id.date_picker_ok).setOnClickListener(this);

        mHideYearStateTv = (TextView) contentView.findViewById(R.id.date_picker_hide_year_text);
        mHideYearStateTv.setOnClickListener(this);

        mGregorianIv = (ImageView) contentView.findViewById(R.id.date_picker_type_gregorian);
        mGregorianIv.setOnClickListener(this);

        mLunarIv = (ImageView) contentView.findViewById(R.id.date_picker_type_lunar);
        mLunarIv.setOnClickListener(this);

        mTitle = (TextView) contentView.findViewById(R.id.date_picker_title);

        if (type == OnDateSetListener.TYPE_GREGORIAN_NO_YEAR || type == OnDateSetListener.TYPE_LUNAR_NO_YEAR || type == OnDateSetListener.TYPE_ALL) {
            hideYear(true);
        } else {
            hideYear(false);
        }

        setDatePickerType(dateType);

        getWindow().setBackgroundDrawable(new ColorDrawable(Color.TRANSPARENT));
        getWindow().setWindowAnimations(R.style.pop_bottom_in_out_anim_style);
        getWindow().setGravity(Gravity.BOTTOM);
        getWindow().setLayout(ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.WRAP_CONTENT);
        setCanceledOnTouchOutside(true);
    }

    @Override
    public void onClick(View v) {
        switch (v.getId()) {
            case R.id.date_picker_type_gregorian:
                showGregorian();
                break;

            case R.id.date_picker_type_lunar:
                showLunar();
                break;

            case R.id.date_picker_hide_year_text:
                mIsHideYear = !mIsHideYear;
                hideYear(mIsHideYear);
                break;

            case R.id.date_picker_ok:
                mCallBack.onDateSet(mDatePicker, mDatePicker.getDate(), mDatePicker.getDateStr(), getCurrentType());
                dismiss();
                break;
        }
    }

    private int getCurrentType() {
        int type = OnDateSetListener.TYPE_GREGORIAN_NO_YEAR;

        if (mDatePicker.getDateType() == LunarDatePicker.DATETYPE.GREGORIAN) {
            if (mDatePicker.showYear())
                type = OnDateSetListener.TYPE_GREGORIAN_YEAR;
            else
                type = OnDateSetListener.TYPE_GREGORIAN_NO_YEAR;
        } else {
            if (mDatePicker.showYear())
                type = OnDateSetListener.TYPE_LUNAR_YEAR;
            else
                type = OnDateSetListener.TYPE_LUNAR_NO_YEAR;
        }
        return type;
    }

    private void hideYear(boolean hideYear) {
        if (hideYear) {
            mHideYearStateTv.setText(R.string.date_picker_dialog_show_year);
            mDatePicker.setYearVisible(View.GONE);
        } else {
            mHideYearStateTv.setText(R.string.date_picker_dialog_hide_year);
            mDatePicker.setYearVisible(View.VISIBLE);
        }
        mIsHideYear = hideYear;
    }

    private void setDatePickerType(LunarDatePicker.DATETYPE type) {
        if (type == LunarDatePicker.DATETYPE.GREGORIAN) {
            showGregorian();
        } else {
            showLunar();
        }
    }

    private void showGregorian() {
        if (!mGregorianIv.isSelected()) {
            mGregorianIv.setSelected(true);
            mLunarIv.setSelected(false);
            mDatePicker.setDateType(LunarDatePicker.DATETYPE.GREGORIAN);
        }
    }

    private void showLunar() {
        if (!mLunarIv.isSelected()) {
            mLunarIv.setSelected(true);
            mGregorianIv.setSelected(false);
            mDatePicker.setDateType(LunarDatePicker.DATETYPE.LUNAR);
        }
    }


    /**
     * 隐藏年份隐藏显示控制按钮，
     * 隐藏日历类别切换按钮
     * 显示标题
     */
    public void hideYearSwitchAndTypeSel() {
        mLunarIv.setVisibility(View.GONE);
        mGregorianIv.setVisibility(View.GONE);
        mHideYearStateTv.setVisibility(View.GONE);
        mTitle.setVisibility(View.VISIBLE);
    }

    @Override
    public void onDateChanged(LunarDatePicker view, Calendar date, String dateStr, LunarDatePicker.DATETYPE type) {
        mSetDateCalendar = date;
        mDateStr = dateStr;
    }

    public void updateDate(int year, int monthofYear, int dayOfMonth, int type) {
        updateDate(year, monthofYear, dayOfMonth, 0, 0, type);
    }

    public void updateDate(int year, int monthOfYear, int dayOfMonth, int hour, int minute, int type) {
        if (type == OnDateSetListener.TYPE_GREGORIAN_NO_YEAR || type == OnDateSetListener.TYPE_LUNAR_NO_YEAR || type == OnDateSetListener.TYPE_ALL) {
            hideYear(true);
        } else {
            hideYear(false);
        }

        LunarDatePicker.DATETYPE dateType = LunarDatePicker.DATETYPE.GREGORIAN;
        if (type == OnDateSetListener.TYPE_LUNAR_NO_YEAR || type == OnDateSetListener.TYPE_LUNAR_YEAR) {
            dateType = LunarDatePicker.DATETYPE.LUNAR;
            Calendar c = Calendar.getInstance(Locale.CHINA);
            c.set(year, monthOfYear, dayOfMonth);
            Lunar l = new Lunar(c);
            int lm = Lunar.leapMonth(l.numeric_year());
            if ((lm > 0 && l.numbric_month() > lm) || l.isLeapMonth()) {//如果有闰月，而且月份大于闰月，或者刚好是闰月 则月份的索引不变
                monthOfYear = l.numbric_month();
            } else {
                monthOfYear = l.numbric_month() - 1;
            }
            mDatePicker.updateDate(l.numeric_year(), monthOfYear, l.numbric_day(), dateType);
        } else if (type == OnDateSetListener.TYPE_GREGORIAN_NO_YEAR || type == OnDateSetListener.TYPE_GREGORIAN_YEAR) {
            dateType = LunarDatePicker.DATETYPE.GREGORIAN;
            mDatePicker.updateDate(year, monthOfYear, dayOfMonth, dateType);
        } else if (type == OnDateSetListener.TYPE_ALL) {
            dateType = LunarDatePicker.DATETYPE.ALL;
            mDatePicker.updateDate(year, monthOfYear, dayOfMonth, hour, minute, dateType);
        }
        setDatePickerType(dateType);
    }

    @Override
    public Bundle onSaveInstanceState() {
        Bundle state = super.onSaveInstanceState();
        state.putInt(YEAR, mDatePicker.getYear());
        state.putInt(MONTH, mDatePicker.getMonth());
        state.putInt(DAY, mDatePicker.getDayOfMonth());
        state.putInt(Hour, mDatePicker.getHour());
        state.putInt(Minute, mDatePicker.getMinute());
        state.putSerializable(DATETYPE, mDatePicker.getDateType());
        return state;
    }

    @Override
    public void onRestoreInstanceState(Bundle savedInstanceState) {
        super.onRestoreInstanceState(savedInstanceState);
        int year = savedInstanceState.getInt(YEAR);
        int month = savedInstanceState.getInt(MONTH);
        int day = savedInstanceState.getInt(DAY);
        int hour = savedInstanceState.getInt(Hour);
        int minute = savedInstanceState.getInt(Minute);
        LunarDatePicker.DATETYPE type = (LunarDatePicker.DATETYPE) savedInstanceState.getSerializable(DATETYPE);
        mDatePicker.init(year, month, day, hour, minute, type, this);
    }

}
